/*
 *Copyright (c) [2019-2020]  C2comm, Inc.  All rights reserved.
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; If not, see <https://www.gnu.org/licenses/>
 */

/*
 *Vendor: C2comm
 *Version: 1.0
 *Filename: CompressPCFSelect.v
 *Target Device: Altera
 *Author : 刘晓骏
*/

module CompressPCFSelect(
    input  wire         SYS2CORE_clk,
    input  wire         SYS2CORE_rst_n,
    
    input  wire [ 47:0] G_device_clk,
    
    input  wire [336:0] CONF2CORE_cm_static_conf,
    
    input  wire         CC2PP_compress_end,

    input  wire         PAC2CPS_pcf_rx_cb_wr_0,
    input  wire [ 85:0] PAC2CPS_pcf_rx_cb_0,
    output wire         CPS2PAC_pcf_rx_cb_ready_0,

    input  wire         PAC2CPS_pcf_rx_cb_wr_1,
    input  wire [ 85:0] PAC2CPS_pcf_rx_cb_1,
    output wire         CPS2PAC_pcf_rx_cb_ready_1,

    input  wire         PAC2CPS_pcf_rx_cb_wr_2,
    input  wire [ 85:0] PAC2CPS_pcf_rx_cb_2,
    output wire         CPS2PAC_pcf_rx_cb_ready_2,

    input  wire         PAC2CPS_pcf_rx_cb_wr_3,
    input  wire [ 85:0] PAC2CPS_pcf_rx_cb_3,
    output wire         CPS2PAC_pcf_rx_cb_ready_3,
    
    output reg          PP2CC_pcf_rx_cb_wrreq,
    output reg  [ 85:0] PP2CC_pcf_rx_cb,
    input  wire         CC2PP_pcf_rx_cb_wrack  
);
/*//////////////////////////////////////////////////////////
                    中间变量声明区域
*///////////////////////////////////////////////////////////
//本模块中所有中间变量(wire/reg/parameter)在此集中声明 
wire        pcbuffer_wrreq_0;
wire [85:0] pcbuffer_wdata_0;
reg         pcbuffer_wrack_0;

wire        pcbuffer_wrreq_1;
wire [85:0] pcbuffer_wdata_1;
reg         pcbuffer_wrack_1;

wire        pcbuffer_wrreq_2;
wire [85:0] pcbuffer_wdata_2;
reg         pcbuffer_wrack_2;

wire        pcbuffer_wrreq_3;
wire [85:0] pcbuffer_wdata_3;
reg         pcbuffer_wrack_3;

reg  [19:0] start_pit;

reg  [1:0]  curr_id;
reg  [1:0]  next_id;
/*//////////////////////////////////////////////////////////
                     配置信号计算(压缩起始时刻)
*///////////////////////////////////////////////////////////
always @(posedge SYS2CORE_clk) 
    start_pit <=  CONF2CORE_cm_static_conf[334:315] + CONF2CORE_cm_static_conf[314:295];

/*//////////////////////////////////////////////////////////
                     输出队列选择
*///////////////////////////////////////////////////////////
always @* begin
    if     (pcbuffer_wrreq_0 == 1'b1)  next_id = 2'd0;
    else if(pcbuffer_wrreq_1 == 1'b1)  next_id = 2'd1;
    else if(pcbuffer_wrreq_2 == 1'b1)  next_id = 2'd2;
    else if(pcbuffer_wrreq_3 == 1'b1)  next_id = 2'd3;
    else                               next_id = 2'd0;
end
always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(SYS2CORE_rst_n == 1'b0) begin
        curr_id <= 2'b0;
    end
    else begin
        if((G_device_clk == start_pit) || (CC2PP_compress_end)) 
            curr_id <= next_id;
        else
            curr_id <= curr_id;
    end
end
/*//////////////////////////////////////////////////////////
                     压缩选择
*///////////////////////////////////////////////////////////
always @* begin
    if(G_device_clk >= start_pit) begin
        case(curr_id)
            2'b0: begin
                PP2CC_pcf_rx_cb_wrreq = pcbuffer_wrreq_0;
                PP2CC_pcf_rx_cb       = pcbuffer_wdata_0;
                
                pcbuffer_wrack_0      = CC2PP_pcf_rx_cb_wrack;
                pcbuffer_wrack_1      = 1'b0;
                pcbuffer_wrack_2      = 1'b0;
                pcbuffer_wrack_3      = 1'b0;
            end
            
            2'd1: begin
                PP2CC_pcf_rx_cb_wrreq = pcbuffer_wrreq_1;
                PP2CC_pcf_rx_cb       = pcbuffer_wdata_1;
                
                pcbuffer_wrack_0      = 1'b0;
                pcbuffer_wrack_1      = CC2PP_pcf_rx_cb_wrack;
                pcbuffer_wrack_2      = 1'b0;
                pcbuffer_wrack_3      = 1'b0;
            end
            
            2'd2: begin
                PP2CC_pcf_rx_cb_wrreq = pcbuffer_wrreq_2;
                PP2CC_pcf_rx_cb       = pcbuffer_wdata_2;
                
                pcbuffer_wrack_0      = 1'b0;
                pcbuffer_wrack_1      = 1'b0;
                pcbuffer_wrack_2      = CC2PP_pcf_rx_cb_wrack;
                pcbuffer_wrack_3      = 1'b0;
            end
            
            2'd3: begin
                PP2CC_pcf_rx_cb_wrreq = pcbuffer_wrreq_3;
                PP2CC_pcf_rx_cb       = pcbuffer_wdata_3;
                
                pcbuffer_wrack_0      = 1'b0;
                pcbuffer_wrack_1      = 1'b0;
                pcbuffer_wrack_2      = 1'b0;
                pcbuffer_wrack_3      = CC2PP_pcf_rx_cb_wrack;
            end
            
            default: begin
                PP2CC_pcf_rx_cb_wrreq = 1'b0;
                PP2CC_pcf_rx_cb       = 38'b0;
                
                pcbuffer_wrack_0      = 1'b0;
                pcbuffer_wrack_1      = 1'b0;
                pcbuffer_wrack_2      = 1'b0;
                pcbuffer_wrack_3      = 1'b0;
            end
        endcase
    end
    else begin
        PP2CC_pcf_rx_cb_wrreq = 1'b0;
        PP2CC_pcf_rx_cb       = 38'b0;
        
        pcbuffer_wrack_0      = 1'b0;
        pcbuffer_wrack_1      = 1'b0;
        pcbuffer_wrack_2      = 1'b0;
        pcbuffer_wrack_3      = 1'b0;
    end
end

/*//////////////////////////////////////////////////////////
                   IP调用区域
*///////////////////////////////////////////////////////////
//本模块调用的所有IP在该区域实例化
//例如fifo/ram/grant之类的IP.... 
InportBuffer #(
    .DWIDTH(86)
)PcfCbBuffer_0(
    .clk(SYS2CORE_clk),
    .rst_n(SYS2CORE_rst_n),

    .idata_valid(PAC2CPS_pcf_rx_cb_wr_0),
    .idata(PAC2CPS_pcf_rx_cb_0),
    .idata_ready(CPS2PAC_pcf_rx_cb_ready_0),

    .odata_wrreq(pcbuffer_wrreq_0),
    .odata(pcbuffer_wdata_0),
    .odata_wrack(pcbuffer_wrack_0)
); 

InportBuffer #(
    .DWIDTH(86)
)PcfCbBuffer_1(
    .clk(SYS2CORE_clk),
    .rst_n(SYS2CORE_rst_n),

    .idata_valid(PAC2CPS_pcf_rx_cb_wr_1),
    .idata(PAC2CPS_pcf_rx_cb_1),
    .idata_ready(CPS2PAC_pcf_rx_cb_ready_1),

    .odata_wrreq(pcbuffer_wrreq_1),
    .odata(pcbuffer_wdata_1),
    .odata_wrack(pcbuffer_wrack_1)
); 

InportBuffer #(
    .DWIDTH(86)
)PcfCbBuffer_2(
    .clk(SYS2CORE_clk),
    .rst_n(SYS2CORE_rst_n),

    .idata_valid(PAC2CPS_pcf_rx_cb_wr_2),
    .idata(PAC2CPS_pcf_rx_cb_2),
    .idata_ready(CPS2PAC_pcf_rx_cb_ready_2),

    .odata_wrreq(pcbuffer_wrreq_2),
    .odata(pcbuffer_wdata_2),
    .odata_wrack(pcbuffer_wrack_2)
); 

InportBuffer #(
    .DWIDTH(86)
)PcfCbBuffer_3(
    .clk(SYS2CORE_clk),
    .rst_n(SYS2CORE_rst_n),

    .idata_valid(PAC2CPS_pcf_rx_cb_wr_3),
    .idata(PAC2CPS_pcf_rx_cb_3),
    .idata_ready(CPS2PAC_pcf_rx_cb_ready_3),

    .odata_wrreq(pcbuffer_wrreq_3),
    .odata(pcbuffer_wdata_3),
    .odata_wrack(pcbuffer_wrack_3)
); 


endmodule
/*
CompressPCFSelect CompressPCFSelect_inst(
    .SYS2CORE_clk(),
    .SYS2CORE_rst_n(),

    .G_device_clk(),

    .CONF2CORE_cm_static_conf(),

    .CC2PP_compress_end(),

    .PAC2CPS_pcf_rx_cb_wr_0(),
    .PAC2CPS_pcf_rx_cb_0(),
    .CPS2PAC_pcf_rx_cb_ready_0(),

    .PAC2CPS_pcf_rx_cb_wr_1(),
    .PAC2CPS_pcf_rx_cb_1(),
    .CPS2PAC_pcf_rx_cb_ready_1(),

    .PAC2CPS_pcf_rx_cb_wr_2(),
    .PAC2CPS_pcf_rx_cb_2(),
    .CPS2PAC_pcf_rx_cb_ready_2(),

    .PAC2CPS_pcf_rx_cb_wr_3(),
    .PAC2CPS_pcf_rx_cb_3(),
    .CPS2PAC_pcf_rx_cb_ready_3(),

    .PP2CC_pcf_rx_cb_wrreq(),
    .PP2CC_pcf_rx_cb(),
    .CC2PP_pcf_rx_cb_wrack()  
);
*/